home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume21 / amd / part07 < prev    next >
Encoding:
Internet Message Format  |  1990-04-10  |  47.0 KB

  1. Subject:  v21i095:  An Automounter for NFS systems, Part07/13
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 43377324 826a6f70 f46c1739 5724dd32
  5.  
  6. Submitted-by: Jan-Simon Pendry <jsp@doc.ic.ac.uk>
  7. Posting-number: Volume 21, Issue 95
  8. Archive-name: amd/part07
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 7 (of 13)."
  17. # Contents:  Makefile.com amq.c get_args.c mapc.c
  18. # Wrapped by rsalz@papaya.bbn.com on Tue Apr 10 15:12:08 1990
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'Makefile.com' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'Makefile.com'\"
  22. else
  23. echo shar: Extracting \"'Makefile.com'\" \(9964 characters\)
  24. sed "s/^X//" >'Makefile.com' <<'END_OF_FILE'
  25. X#
  26. X# $Id: Makefile.com,v 5.1.1.2 90/01/11 16:46:47 jsp Exp Locker: jsp $
  27. X#
  28. X# Copyright (c) 1990 Jan-Simon Pendry
  29. X# Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  30. X# Copyright (c) 1990 The Regents of the University of California.
  31. X# All rights reserved.
  32. X#
  33. X# This code is derived from software contributed to Berkeley by
  34. X# Jan-Simon Pendry at Imperial College, London.
  35. X#
  36. X# Redistribution and use in source and binary forms are permitted
  37. X# provided that the above copyright notice and this paragraph are
  38. X# duplicated in all such forms and that any documentation,
  39. X# advertising materials, and other materials related to such
  40. X# distribution and use acknowledge that the software was developed
  41. X# by Imperial College of Science, Technology and Medicine, London, UK.
  42. X# The names of the College and University may not be used to endorse
  43. X# or promote products derived from this software without specific
  44. X# prior written permission.
  45. X# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  46. X# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  47. X# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  48. X#
  49. X#    %W% (Berkeley) %G%
  50. X#
  51. X
  52. X#
  53. X# -------- Users may care to override these values --------
  54. X#
  55. X# Any of these values can be overridden by redefining them
  56. X# in a file called Makefile.local or Makefile.local.foo (where
  57. X# "foo" is the OS name)
  58. X#
  59. X
  60. X# Where to install amd
  61. XETC = /usr/local/etc
  62. X
  63. X# With what to install amd
  64. XINSTALL = install
  65. XINSTALL_BIN = ${INSTALL} -c -m 711 -o root
  66. X
  67. X# Uncomment the next CC line if you want to use GNU CC
  68. X# Better yet - put the definition in Makefile.local.<foo>
  69. X#CC = gcc ${GCCOPTS}
  70. XGCCOPTS = -fcombine-regs -W -Wunused -fstrength-reduce #-finline-functions
  71. X
  72. X# Basic C compiler options
  73. XCCOPTS = -O
  74. X
  75. X# These are for testing/debugging...
  76. X# Best to put your own definitions in Makefile.local.<foo>
  77. X#CCOPTS =  -g
  78. X# Turn on -DDEBUG if you want a running commentary
  79. X#DEBUG = -DDEBUG
  80. X
  81. X# Define RPCINC if Sun RPC header files are not in the standard place
  82. XRPCINC = #-I../../rpc
  83. X
  84. X# Define RPCGEN as the name of your Sun *RPC/4* RPCGEN program (not RPC/3)
  85. XRPCGEN = rpcgen
  86. X
  87. X# System C Compiler - one that is FULLY call compatible with your C libraries
  88. XSYSCC = cc
  89. XSYSCCFLAGS = ${CFLAGS}
  90. X
  91. X# For old makes
  92. XSHELL = /bin/sh
  93. X
  94. X# -------- YOU SHOULD NOT NEED TO CHANGE ANYTHING BELOW THIS LINE --------
  95. X
  96. X# Magic
  97. XOS_HDR = os-${OS}.h
  98. XOSDEF = -DOS_HDR=\"${OS_HDR}\" -DOS_REP=\"${OS}\" -DARCH_REP=\"${ARCH}\"
  99. XCFLAGS = ${CCOPTS} ${DEBUG} ${OSDEF} -I..
  100. X
  101. X# Basename of the program we are trying to build
  102. XAMD = amd
  103. XAMQ = amq
  104. XMKMAP = mk-amd-map
  105. X
  106. XCC_COMPILE = ${CC} -c ${CFLAGS} ${RPCINC} ${CONFIG}
  107. XSYSCC_COMPILE = ${SYSCC} -c ${SYSCCFLAGS} ${RPCINC} ${CONFIG}
  108. X
  109. X#
  110. X# Keeps sysV make happy:
  111. X#
  112. XVPATH = ..
  113. X
  114. X#
  115. X# Autmounter modules
  116. X#
  117. XMOUNTOBJ = \
  118. X    afs_ops.o am_ops.o clock.o efs_ops.o \
  119. X    mapc.o info_file.o info_hes.o info_ndbm.o info_yp.o map.o \
  120. X    srvr_afs.o srvr_nfs.o \
  121. X    mntfs.o misc_rpc.o mount_fs.o mount_xdr.o \
  122. X    mtab.o nfs_ops.o nfs_prot_svc.o \
  123. X    nfs_start.o nfs_stubs.o nfs_prot_xdr.o \
  124. X    opts.o pfs_ops.o rpc_fwd.o \
  125. X    sched.o sfs_ops.o \
  126. X    amq_svc.o amq_subr.o umount_fs.o util.o \
  127. X    ufs_ops.o ifs_ops.o am.o get_args.o \
  128. X    rcs_info.o restart.o
  129. X
  130. XAMQOBJ = \
  131. X    amq.o amq_clnt.o amq_xdr.o misc_rpc.o
  132. X
  133. XMAPOBJ = \
  134. X    mk-amd-map.o
  135. X
  136. X#
  137. X# Files defining different O/S flavors
  138. X#
  139. XOS_FILES = \
  140. X    os-acis43.h \
  141. X    os-aux.h \
  142. X    os-bsd44.h Makefile.bsd44 \
  143. X    os-concentrix.h \
  144. X    os-defaults.h \
  145. X    os-hlh42.h \
  146. X    os-hpux.h Makefile.hpux hpux.h \
  147. X    os-riscix.h \
  148. X    os-sos3.h \
  149. X    os-sos4.h \
  150. X    os-u2_2.h u2_2-nfs.h \
  151. X    os-u3_0.h \
  152. X    os-umax43.h \
  153. X    os-utx32.h \
  154. X    os-xinu43.h
  155. X
  156. X# Experimental...
  157. XEXPERIMENTAL_OS_FILES = os-aix2.h Makefile.aix2
  158. X
  159. X#
  160. X# Other files that need to be shipped
  161. X#
  162. XBITS    = \
  163. X    RELEASE \
  164. X    COPYRIGHT \
  165. X    Configure \
  166. X    ChangeLog \
  167. X    INSTALL \
  168. X    Makefile \
  169. X    Makefile.com \
  170. X    Makefile.config \
  171. X    patchlevel.h \
  172. X    newvers.sh \
  173. X    README \
  174. X    WishList \
  175. X    a_master \
  176. X    amd-man \
  177. X    amq-man \
  178. X    amd.start.ex \
  179. X    arch \
  180. X    os-type
  181. X
  182. X#
  183. X# Files to ship
  184. X#
  185. XSHIP    = \
  186. X    afs_ops.c am.c am.h am_ops.c amq.c amq.h amq.x amq_clnt.c \
  187. X    amq_subr.c amq_svc.c amq_xdr.c clock.c \
  188. X    efs_ops.c fs.h get_args.c ifs_ops.c info_file.c info_hes.c \
  189. X    info_ndbm.c info_yp.c map.c mapc.c misc_rpc.c mk-amd-map.c \
  190. X    mntfs.c mount.h mount.x mount_fs.c mount_xdr.c mtab.c nfs_ops.c \
  191. X    nfs_prot.h nfs_prot.x nfs_prot_svc.c nfs_prot_xdr.c nfs_start.c \
  192. X    nfs_stubs.c opts.c pfs_ops.c rcs_info.c restart.c rpc_fwd.c sched.c \
  193. X    sfs_ops.c srvr_afs.c srvr_nfs.c ufs_ops.c umount_fs.c util.c uwait.h \
  194. X    ${OS_FILES} ${BITS}
  195. X
  196. XDOCS    = \
  197. X    doc/nh.sty doc/nh.doc \
  198. X    doc/amd.bbl doc/amd.bib \
  199. X    doc/amd.tex
  200. X
  201. XEXAMPLES = \
  202. X    examples/am.master examples/amd.home \
  203. X    examples/amd.homes examples/amd.vol
  204. X
  205. XSCRIPTS = \
  206. X    scripts/build-userinfo \
  207. X    scripts/get-homes \
  208. X    scripts/mk-home-maps \
  209. X    scripts/auto-banner
  210. X
  211. X#
  212. X# Files to print
  213. X#
  214. XPRINT    = ${SHIP} ${SCRIPTS}
  215. X
  216. X#
  217. X# What to build
  218. X#
  219. Xall: ${AMQ} ${AMD} ${MKMAP}
  220. X
  221. X${AMD}: ${MOUNTOBJ} version.${AMD}
  222. X    @sh ../newvers.sh $@
  223. X    ${CC_COMPILE} vers.$@.c
  224. X    @rm -f $@
  225. X    ${CC} -o $@ ${CFLAGS} ${MOUNTOBJ} vers.$@.o ${XLIBDIR} ${DBM} ${RPCLIB} ${RESOLV}
  226. X
  227. X${AMQ}: ${AMQOBJ}
  228. X    @rm -f $@
  229. X    ${CC} -o $@ ${CFLAGS} ${AMQOBJ} ${RPCLIB} ${XLIBDIR} ${RESOLV}
  230. X
  231. X${MKMAP}: ${MAPOBJ}
  232. X    @rm -f $@
  233. X    ${CC} -o $@ ${CFLAGS} ${MAPOBJ} ${DBM}
  234. X
  235. Xversion.${AMD}: ../RELEASE
  236. X#    @echo Starting ${AMD} versions from zero ...
  237. X    @rm -f $@
  238. X    @echo 0 > $@
  239. X
  240. Xlint:
  241. X    @for i in ${MOUNTOBJ:.o=.c}; do \
  242. X        c="$$c ../$$i"; \
  243. X    done; \
  244. X    echo lint -chaax ${CFLAGS} $$c; \
  245. X    lint -chaax ${CFLAGS} $$c
  246. X
  247. Xcount:
  248. X    cat ${MOUNTOBJ:.o=.c} | grep -v '^#' | /lib/cpp | \
  249. X    sed -e 's/[     ]*$$//' -e '/^$$/d' | \
  250. X    wc
  251. X
  252. XFRC:
  253. X
  254. X${MOUNTOBJ}: ../am.h ../${OS_HDR} ../os-defaults.h ../fs.h ../Makefile.config
  255. X${AMQOBJ}: ../amq.h ../${OS_HDR} ../os-defaults.h
  256. X${MAPOBJ}: ../am.h ../${OS_HDR} ../os-defaults.h
  257. X
  258. Xnfs_start.o: ../amq.h
  259. X../amq.c ../amq_clnt.c ../amq_xdr.c ../amq_svc.c ../amq_subr.c: ../amq.h
  260. X
  261. X# We can't use gcc here (at least on sparc) ....
  262. Xamq.o: ../amq.c; ${SYSCC_COMPILE} ../amq.c
  263. Xamq_clnt.o: ../amq_clnt.c; ${SYSCC_COMPILE} ../amq_clnt.c
  264. Xinfo_ndbm.o: ../info_ndbm.c; ${SYSCC_COMPILE} ../info_ndbm.c
  265. Xmk-amd-map.o: ../mk-amd-map.c; ${SYSCC_COMPILE} ../mk-amd-map.c
  266. X
  267. X#amq.h: amq.x
  268. X#    ${RPCGEN} -h -o $@ amq.x
  269. X#    @echo amq.h is out of date wrt amq.x - please fix by hand
  270. X
  271. X#amq_xdr.c: amq.x
  272. X#    ${RPCGEN} -c -o $@ amq.x
  273. X#    @echo amq_xdr.c is out of date wrt amq.x - please fix by hand
  274. X
  275. X#amq_svc.c: amq.x
  276. X#    ${RPCGEN} -m -o $@ amq.x
  277. X#    @echo amq_svc.c is out of date wrt amq.x - please fix by hand
  278. X
  279. X#amq_clnt.c: amq.x
  280. X#    ${RPCGEN} -l -o $@ amq.x
  281. X#    @echo amq_clnt.c is out of date wrt amq.x - please fix by hand
  282. X
  283. X#
  284. X# Don't really need the next two
  285. X#
  286. X#mount_xdr.c: mount.x
  287. X#    ${RPCGEN} -c -o $@ amq.x
  288. X#    @echo mount_xdr.c is out of date wrt mount.x - please fix by hand
  289. X
  290. X#mount.h: mount.x
  291. X#    ${RPCGEN} -h -o $@ mount.x
  292. X#    @echo mount.h is out of date wrt mount.x - please fix by hand
  293. X
  294. Xprint: ${PRINT}
  295. X    enscript -2Grf Courier7 ${PRINT}
  296. X
  297. Xsharfile: ${AMD}.shar
  298. X${AMD}.shar: ${SHIP} ${DOCS} ${EXAMPLES} ${SCRIPTS}
  299. X    shar -o $@ ${SHIP} doc ${DOCS} examples ${EXAMPLES} scripts ${SCRIPTS}
  300. X
  301. Xtarfile: ${AMD}.tar.Z
  302. X${AMD}.tar.Z: ${SHIP} ${DOCS} ${EXAMPLES} ${SCRIPTS}
  303. X    tar cf - ${SHIP} ${DOCS} ${EXAMPLES} ${SCRIPTS} | compress > $@
  304. X
  305. Xuufile: tarfile
  306. X    uuencode < ${AMD}.tar.Z ${AMD}.tar.Z > ${AMD}.tar.Z.UU
  307. X
  308. Xinstall: all
  309. X    ${INSTALL_BIN} ${AMD} ${ETC}/${AMD}
  310. X    ${INSTALL_BIN} ${AMQ} ${ETC}/${AMQ}
  311. X    ${INSTALL_BIN} ${MKMAP} ${ETC}/${MKMAP}
  312. X    @echo Please install the manual pages by hand
  313. X
  314. Xclean:
  315. X    -rm -f ${AMD} ${AMQ} ${MKMAP} *.o a.out core #mtab
  316. X
  317. X#co:
  318. X#    co -l -r${REL} ${SHIP}
  319. X#
  320. X#release:
  321. X#    ci -u -r${REL} -f -m'Version ${VER}' -n${NAME} -s'${NAME}' ${SHIP}
  322. X
  323. Xpat:
  324. X    @touch RELEASE
  325. X    pat -n
  326. X
  327. Xdiffs:
  328. X    @rcsdiff -q -c2 -r${NAME} ${SHIP} | \
  329. X        grep -v '^No differences encountered$$'
  330. X
  331. Xafs_ops.o: ../afs_ops.c; ${CC_COMPILE} ../afs_ops.c
  332. Xam.o: ../am.c; ${CC_COMPILE} ../am.c
  333. Xam_ops.o: ../am_ops.c; ${CC_COMPILE} ../am_ops.c
  334. Xclock.o: ../clock.c; ${CC_COMPILE} ../clock.c
  335. Xget_args.o: ../get_args.c; ${CC_COMPILE} ../get_args.c
  336. Xefs_ops.o: ../efs_ops.c; ${CC_COMPILE} ../efs_ops.c
  337. Xifs_ops.o: ../ifs_ops.c; ${CC_COMPILE} ../ifs_ops.c
  338. Xinfo_file.o: ../info_file.c; ${CC_COMPILE} ../info_file.c
  339. Xinfo_hes.o: ../info_hes.c; ${CC_COMPILE} ../info_hes.c
  340. X#info_ndbm.o: ../info_ndbm.c; ${CC_COMPILE} ../info_ndbm.c
  341. Xinfo_yp.o: ../info_yp.c; ${CC_COMPILE} ../info_yp.c
  342. Xmap.o: ../map.c; ${CC_COMPILE} ../map.c
  343. Xmapc.o: ../mapc.c; ${CC_COMPILE} ../mapc.c
  344. Xmisc_rpc.o: ../misc_rpc.c; ${CC_COMPILE} ../misc_rpc.c
  345. X#mk-amd-map.o: ../mk-amd-map.c; ${CC_COMPILE} ../mk-amd-map.c
  346. Xmntfs.o: ../mntfs.c; ${CC_COMPILE} ../mntfs.c
  347. Xmount_fs.o: ../mount_fs.c; ${CC_COMPILE} ../mount_fs.c
  348. Xmount_xdr.o: ../mount_xdr.c; ${CC_COMPILE} ../mount_xdr.c
  349. Xmtab.o: ../mtab.c; ${CC_COMPILE} ../mtab.c
  350. Xnfs_ops.o: ../nfs_ops.c; ${CC_COMPILE} ../nfs_ops.c
  351. Xnfs_prot_svc.o: ../nfs_prot_svc.c; ${CC_COMPILE} ../nfs_prot_svc.c
  352. Xnfs_start.o: ../nfs_start.c; ${CC_COMPILE} ../nfs_start.c
  353. Xnfs_stubs.o: ../nfs_stubs.c; ${CC_COMPILE} ../nfs_stubs.c
  354. Xnfs_prot_xdr.o: ../nfs_prot_xdr.c; ${CC_COMPILE} ../nfs_prot_xdr.c
  355. Xopts.o: ../opts.c; ${CC_COMPILE} ../opts.c
  356. Xpfs_ops.o: ../pfs_ops.c; ${CC_COMPILE} ../pfs_ops.c
  357. Xrcs_info.o: ../rcs_info.c; ${CC_COMPILE} ../rcs_info.c
  358. Xrestart.o: ../restart.c; ${CC_COMPILE} ../restart.c
  359. Xrpc_fwd.o: ../rpc_fwd.c; ${CC_COMPILE} ../rpc_fwd.c
  360. Xsched.o: ../sched.c; ${CC_COMPILE} ../sched.c
  361. Xsfs_ops.o: ../sfs_ops.c; ${CC_COMPILE} ../sfs_ops.c
  362. Xsrvr_afs.o: ../srvr_afs.c; ${CC_COMPILE} ../srvr_afs.c
  363. Xsrvr_nfs.o: ../srvr_nfs.c; ${CC_COMPILE} ../srvr_nfs.c
  364. X#svc_udp2.o: ../svc_udp2.c; ${CC_COMPILE} ../svc_udp2.c
  365. X#tfs_ops.o: ../tfs_ops.c; ${CC_COMPILE} ../tfs_ops.c
  366. Xufs_ops.o: ../ufs_ops.c; ${CC_COMPILE} ../ufs_ops.c
  367. Xumount_fs.o: ../umount_fs.c; ${CC_COMPILE} ../umount_fs.c
  368. Xutil.o: ../util.c; ${CC_COMPILE} ../util.c
  369. Xversion.o: ../version.c; ${CC_COMPILE} ../version.c
  370. Xamq_svc.o: ../amq_svc.c; ${CC_COMPILE} ../amq_svc.c
  371. Xamq_subr.o: ../amq_subr.c; ${CC_COMPILE} ../amq_subr.c
  372. X#amq.o: ../amq.c; ${CC_COMPILE} ../amq.c
  373. X#amq_clnt.o: ../amq_clnt.c; ${CC_COMPILE} ../amq_clnt.c
  374. Xamq_xdr.o: ../amq_xdr.c; ${CC_COMPILE} ../amq_xdr.c
  375. END_OF_FILE
  376. if test 9964 -ne `wc -c <'Makefile.com'`; then
  377.     echo shar: \"'Makefile.com'\" unpacked with wrong size!
  378. fi
  379. # end of 'Makefile.com'
  380. fi
  381. if test -f 'amq.c' -a "${1}" != "-c" ; then 
  382.   echo shar: Will not clobber existing file \"'amq.c'\"
  383. else
  384. echo shar: Extracting \"'amq.c'\" \(11634 characters\)
  385. sed "s/^X//" >'amq.c' <<'END_OF_FILE'
  386. X/*
  387. X * $Id: amq.c,v 5.1.1.2 90/01/11 17:01:11 jsp Exp Locker: jsp $
  388. X *
  389. X * Copyright (c) 1990 Jan-Simon Pendry
  390. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  391. X * Copyright (c) 1990 The Regents of the University of California.
  392. X * All rights reserved.
  393. X *
  394. X * This code is derived from software contributed to Berkeley by
  395. X * Jan-Simon Pendry at Imperial College, London.
  396. X *
  397. X * Redistribution and use in source and binary forms are permitted
  398. X * provided that the above copyright notice and this paragraph are
  399. X * duplicated in all such forms and that any documentation,
  400. X * advertising materials, and other materials related to such
  401. X * distribution and use acknowledge that the software was developed
  402. X * by Imperial College of Science, Technology and Medicine, London, UK.
  403. X * The names of the College and University may not be used to endorse
  404. X * or promote products derived from this software without specific
  405. X * prior written permission.
  406. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  407. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  408. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  409. X */
  410. X
  411. X/*
  412. X * Automounter query tool
  413. X */
  414. X
  415. X#ifndef lint
  416. Xchar copyright[] = "\
  417. X@(#)Copyright (c) 1990 Jan-Simon Pendry\n\
  418. X@(#)Copyright (c) 1990 Imperial College of Science, Technology & Medicine\n\
  419. X@(#)Copyright (c) 1990 The Regents of the University of California.\n\
  420. X@(#)All rights reserved.\n";
  421. X#endif /* not lint */
  422. X
  423. X#ifndef lint
  424. Xstatic char rcsid[] = "$Id: amq.c,v 5.1.1.2 90/01/11 17:01:11 jsp Exp Locker: jsp $";
  425. Xstatic char sccsid[] = "%W% (Berkeley) %G%";
  426. X#endif /* not lint */
  427. X
  428. X#include "am.h"
  429. X#include "amq.h"
  430. X#include <stdio.h>
  431. X#include <fcntl.h>
  432. X#include <netdb.h>
  433. X
  434. Xchar *progname;
  435. Xstatic int flush_flag;
  436. Xstatic int minfo_flag;
  437. Xstatic int unmount_flag;
  438. Xstatic int stats_flag;
  439. Xstatic char *debug_opts;
  440. Xstatic char *logfile;
  441. Xstatic char *xlog_opt;
  442. Xstatic char localhost[] = "localhost";
  443. Xstatic char *def_server = localhost;
  444. X
  445. Xextern int optind;
  446. Xextern char *optarg;
  447. X
  448. Xstatic struct timeval tmo = { 10, 0 };
  449. X#define    TIMEOUT tmo
  450. X
  451. Xenum show_opt { Full, Stats, Calc, Short, ShowDone };
  452. X
  453. X/*
  454. X * If (e) is Calc then just calculate the sizes
  455. X * Otherwise display the mount node on stdout
  456. X */
  457. Xstatic void show_mti(mt, e, mwid, dwid, twid)
  458. Xamq_mount_tree *mt;
  459. Xenum show_opt e;
  460. Xint *mwid;
  461. Xint *dwid;
  462. Xint *twid;
  463. X{
  464. X    switch (e) {
  465. X    case Calc: {
  466. X        int mw = strlen(mt->mt_mountinfo);
  467. X        int dw = strlen(mt->mt_directory);
  468. X        int tw = strlen(mt->mt_type);
  469. X        if (mw > *mwid) *mwid = mw;
  470. X        if (dw > *dwid) *dwid = dw;
  471. X        if (tw > *twid) *twid = tw;
  472. X    } break;
  473. X
  474. X    case Full: {
  475. X        struct tm *tp = localtime(&mt->mt_mounttime);
  476. Xprintf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
  477. X            *dwid, *dwid,
  478. X            *mt->mt_directory ? mt->mt_directory : "/",    /* XXX */
  479. X            *twid, *twid,
  480. X            mt->mt_type,
  481. X            *mwid, *mwid, 
  482. X            mt->mt_mountinfo,
  483. X            mt->mt_mountpoint,
  484. X
  485. X            mt->mt_mountuid,
  486. X            mt->mt_getattr,
  487. X            mt->mt_lookup,
  488. X            mt->mt_readdir,
  489. X            mt->mt_readlink,
  490. X            mt->mt_statfs,
  491. X
  492. X            tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
  493. X            tp->tm_mon+1, tp->tm_mday,
  494. X            tp->tm_hour, tp->tm_min, tp->tm_sec);
  495. X    } break;
  496. X
  497. X    case Stats: {
  498. X        struct tm *tp = localtime(&mt->mt_mounttime);
  499. Xprintf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n",
  500. X            *dwid, *dwid,
  501. X            *mt->mt_directory ? mt->mt_directory : "/",    /* XXX */
  502. X
  503. X            mt->mt_mountuid,
  504. X            mt->mt_getattr,
  505. X            mt->mt_lookup,
  506. X            mt->mt_readdir,
  507. X            mt->mt_readlink,
  508. X            mt->mt_statfs,
  509. X
  510. X            tp->tm_year > 99 ? tp->tm_year - 100 : tp->tm_year,
  511. X            tp->tm_mon+1, tp->tm_mday,
  512. X            tp->tm_hour, tp->tm_min, tp->tm_sec);
  513. X    } break;
  514. X
  515. X    case Short: {
  516. X        printf("%-*.*s %-*.*s %-*.*s %s\n",
  517. X            *dwid, *dwid,
  518. X            *mt->mt_directory ? mt->mt_directory : "/",
  519. X            *twid, *twid,
  520. X            mt->mt_type,
  521. X            *mwid, *mwid,
  522. X            mt->mt_mountinfo,
  523. X            mt->mt_mountpoint);
  524. X    } break;
  525. X    }
  526. X}
  527. X
  528. X/*
  529. X * Display a mount tree.
  530. X */
  531. Xstatic void show_mt(mt, e, mwid, dwid, pwid)
  532. Xamq_mount_tree *mt;
  533. Xenum show_opt e;
  534. Xint *mwid;
  535. Xint *dwid;
  536. Xint *pwid;
  537. X{
  538. X    while (mt) {
  539. X        show_mti(mt, e, mwid, dwid, pwid);
  540. X        show_mt(mt->mt_next, e, mwid, dwid, pwid);
  541. X        mt = mt->mt_child;
  542. X    }
  543. X}
  544. X
  545. Xstatic void show_mi(ml, e, mwid, dwid, twid)
  546. Xamq_mount_info_list *ml;
  547. Xenum show_opt e;
  548. Xint *mwid;
  549. Xint *dwid;
  550. Xint *twid;
  551. X{
  552. X    int i;
  553. X    switch (e) {
  554. X    case Calc: {
  555. X        for (i = 0; i < ml->amq_mount_info_list_len; i++) {
  556. X            amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
  557. X            int mw = strlen(mi->mi_mountinfo);
  558. X            int dw = strlen(mi->mi_mountpt);
  559. X            int tw = strlen(mi->mi_type);
  560. X            if (mw > *mwid) *mwid = mw;
  561. X            if (dw > *dwid) *dwid = dw;
  562. X            if (tw > *twid) *twid = tw;
  563. X        }
  564. X    } break;
  565. X
  566. X    case Full: {
  567. X        for (i = 0; i < ml->amq_mount_info_list_len; i++) {
  568. X            amq_mount_info *mi = &ml->amq_mount_info_list_val[i];
  569. X            printf("%-*.*s %-*.*s %-*.*s %-3d %s is %s",
  570. X                        *mwid, *mwid, mi->mi_mountinfo,
  571. X                        *dwid, *dwid, mi->mi_mountpt,
  572. X                        *twid, *twid, mi->mi_type,
  573. X                        mi->mi_refc, mi->mi_fserver,
  574. X                        mi->mi_up > 0 ? "up" :
  575. X                        mi->mi_up < 0 ? "starting" : "down");
  576. X            if (mi->mi_error > 0) {
  577. X                extern char *sys_errlist[];
  578. X                extern int sys_nerr;
  579. X                if (mi->mi_error < sys_nerr)
  580. X                    printf(" (%s)", sys_errlist[mi->mi_error]);
  581. X                else
  582. X                    printf(" (Error %d)", mi->mi_error);
  583. X            } else if (mi->mi_error < 0) {
  584. X                fputs(" (in progress)", stdout);
  585. X            }
  586. X            fputc('\n', stdout);
  587. X        }
  588. X    } break;
  589. X    }
  590. X}
  591. X
  592. X/*
  593. X * Display general mount statistics
  594. X */
  595. Xstatic void show_ms(ms)
  596. Xamq_mount_stats *ms;
  597. X{
  598. X    printf("\
  599. Xrequests  stale     mount     mount     unmount\n\
  600. Xdeferred  fhandles  ok        failed    failed\n\
  601. X%-9d %-9d %-9d %-9d %-9d\n",
  602. X    ms->as_drops, ms->as_stale, ms->as_mok, ms->as_merr, ms->as_uerr);
  603. X}
  604. X
  605. Xstatic bool_t
  606. Xxdr_pri_free(xdr_args, args_ptr)
  607. Xxdrproc_t xdr_args;
  608. Xcaddr_t args_ptr;
  609. X{
  610. X    XDR xdr;
  611. X    xdr.x_op = XDR_FREE;
  612. X    return ((*xdr_args)(&xdr, args_ptr));
  613. X}
  614. X
  615. X#ifdef hpux
  616. X#include <cluster.h>
  617. Xstatic char *cluster_server()
  618. X{
  619. X    struct cct_entry *cp;
  620. X
  621. X    if (cnodeid() == 0) {
  622. X        /*
  623. X         * Not clustered
  624. X         */
  625. X        return def_server;
  626. X    }
  627. X
  628. X    while (cp = getccent())
  629. X        if (cp->cnode_type == 'r')
  630. X            return cp->cnode_name;
  631. X
  632. X
  633. X    return def_server;
  634. X}
  635. X#endif
  636. X
  637. X/*
  638. X * MAIN
  639. X */
  640. Xmain(argc, argv)
  641. Xint argc;
  642. Xchar *argv[];
  643. X{
  644. X    int opt_ch;
  645. X    int errs = 0;
  646. X    char *server;
  647. X    struct sockaddr_in server_addr;
  648. X    int s = RPC_ANYSOCK;
  649. X    CLIENT *clnt;
  650. X    struct hostent *hp;
  651. X    int nodefault = 0;
  652. X
  653. X    /*
  654. X     * Compute program name
  655. X     */
  656. X    if (argv[0]) {
  657. X        progname = strrchr(argv[0], '/');
  658. X        if (progname && progname[1])
  659. X            progname++;
  660. X        else
  661. X            progname = argv[0];
  662. X    }
  663. X    if (!progname)
  664. X        progname = "amq";
  665. X
  666. X    /*
  667. X     * Parse arguments
  668. X     */
  669. X    while ((opt_ch = getopt(argc, argv, "fh:l:msux:D:")) != EOF)
  670. X    switch (opt_ch) {
  671. X    case 'f':
  672. X        flush_flag = 1;
  673. X        break;
  674. X
  675. X    case 'h':
  676. X        def_server = optarg;
  677. X        break;
  678. X
  679. X    case 'l':
  680. X        logfile = optarg;
  681. X        nodefault = 1;
  682. X        break;
  683. X
  684. X    case 'm':
  685. X        minfo_flag = 1;
  686. X        nodefault = 1;
  687. X        break;
  688. X
  689. X    case 's':
  690. X        stats_flag = 1;
  691. X        break;
  692. X
  693. X    case 'u':
  694. X        unmount_flag = 1;
  695. X        break;
  696. X
  697. X    case 'x':
  698. X        xlog_opt = optarg;
  699. X        nodefault = 1;
  700. X        break;
  701. X
  702. X    case 'D':
  703. X        debug_opts = optarg;
  704. X        nodefault = 1;
  705. X        break;
  706. X
  707. X    default:
  708. X        errs = 1;
  709. X        break;
  710. X    }
  711. X
  712. X    if (errs) {
  713. Xshow_usage:
  714. X        fprintf(stderr, "\
  715. XUsage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\
  716. X\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts]\n", progname);
  717. X        exit(1);
  718. X    }
  719. X
  720. X#ifdef hpux
  721. X    /*
  722. X     * Figure out root server of cluster
  723. X     */
  724. X    if (def_server == localhost)
  725. X        server = cluster_server();
  726. X    else
  727. X#endif
  728. X    server = def_server;
  729. X
  730. X    /*
  731. X     * Get address of server
  732. X     */
  733. X    if ((hp = gethostbyname(server)) == 0) {
  734. X        fprintf(stderr, "%s: Can't get address of %s\n", progname, server);
  735. X        exit(1);
  736. X    }
  737. X    bzero(&server_addr, sizeof server_addr);
  738. X    server_addr.sin_family = AF_INET;
  739. X    server_addr.sin_addr = *(struct in_addr *) hp->h_addr;
  740. X
  741. X    /*
  742. X     * Create RPC endpoint
  743. X     */
  744. X    clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s);
  745. X    if (clnt == 0) {
  746. X        fprintf(stderr, "%s: ", progname);
  747. X        clnt_pcreateerror(server);
  748. X        exit(1);
  749. X    }
  750. X
  751. X    /*
  752. X     * Control debugging
  753. X     */
  754. X    if (debug_opts) {
  755. X        int *rc;
  756. X        amq_setopt opt;
  757. X        opt.as_opt = AMOPT_DEBUG;
  758. X        opt.as_str = debug_opts;
  759. X        rc = amqproc_setopt_1(&opt, clnt);
  760. X        if (rc && *rc < 0) {
  761. X            fprintf(stderr, "%s: daemon not compiled for debug", progname);
  762. X            errs = 1;
  763. X        } else if (!rc || *rc > 0) {
  764. X            fprintf(stderr, "%s: debug setting for \"%s\" failed\n", progname, debug_opts);
  765. X            errs = 1;
  766. X        }
  767. X    }
  768. X
  769. X    /*
  770. X     * Control logging
  771. X     */
  772. X    if (xlog_opt) {
  773. X        int *rc;
  774. X        amq_setopt opt;
  775. X        opt.as_opt = AMOPT_XLOG;
  776. X        opt.as_str = xlog_opt;
  777. X        rc = amqproc_setopt_1(&opt, clnt);
  778. X        if (!rc || *rc) {
  779. X            fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_opt);
  780. X            errs = 1;
  781. X        }
  782. X    }
  783. X
  784. X    /*
  785. X     * Control log file
  786. X     */
  787. X    if (logfile) {
  788. X        int *rc;
  789. X        amq_setopt opt;
  790. X        opt.as_opt = AMOPT_LOGFILE;
  791. X        opt.as_str = logfile;
  792. X        rc = amqproc_setopt_1(&opt, clnt);
  793. X        if (!rc || *rc) {
  794. X            fprintf(stderr, "%s: setting logfile to \"%s\" failed\n", progname, logfile);
  795. X            errs = 1;
  796. X        }
  797. X    }
  798. X
  799. X    /*
  800. X     * Flush map cache
  801. X     */
  802. X    if (logfile) {
  803. X        int *rc;
  804. X        amq_setopt opt;
  805. X        opt.as_opt = AMOPT_FLUSHMAPC;
  806. X        opt.as_str = "";
  807. X        rc = amqproc_setopt_1(&opt, clnt);
  808. X        if (!rc || *rc) {
  809. X            fprintf(stderr, "%s: amd on %s cannot flush the map cache\n", progname, server);
  810. X            errs = 1;
  811. X        }
  812. X    }
  813. X
  814. X    /*
  815. X     * Mount info
  816. X     */
  817. X    if (minfo_flag) {
  818. X        int dummy;
  819. X        amq_mount_info_list *ml = amqproc_getmntfs_1(&dummy, clnt);
  820. X        if (ml) {
  821. X            int mwid = 0, dwid = 0, twid = 0;
  822. X            show_mi(ml, Calc, &mwid, &dwid, &twid);
  823. X            mwid++; dwid++; twid++;
  824. X            show_mi(ml, Full, &mwid, &dwid, &twid);
  825. X
  826. X        } else {
  827. X            fprintf(stderr, "%s: amd on %s cannot provide mount info\n", progname, server);
  828. X        }
  829. X    }
  830. X
  831. X    /*
  832. X     * Apply required operation to all remaining arguments
  833. X     */
  834. X    if (optind < argc) {
  835. X        do {
  836. X            char *fs = argv[optind++];
  837. X            if (unmount_flag) {
  838. X                /*
  839. X                 * Unmount request
  840. X                 */
  841. X                amqproc_umnt_1(&fs, clnt);
  842. X            } else {
  843. X                /*
  844. X                 * Stats request
  845. X                 */
  846. X                amq_mount_tree_p *mtp = amqproc_mnttree_1(&fs, clnt);
  847. X                if (mtp) {
  848. X                    amq_mount_tree *mt = *mtp;
  849. X                    if (mt) {
  850. X                        int mwid = 0, dwid = 0, twid = 0;
  851. X                        show_mt(mt, Calc, &mwid, &dwid, &twid);
  852. X                        mwid++; dwid++, twid++;
  853. X#ifdef notdef
  854. X        printf("\t%s\n%-*.*s %-*.*s %-*.*s %s\n",
  855. X        "Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@",
  856. X              dwid, dwid, "What", twid, twid, "Type", mwid, mwid, "Info", "Where");
  857. X                        show_mt(mt, Full, &mwid, &dwid, &twid);
  858. X#endif
  859. X        printf("%-*.*s Uid   Getattr Lookup RdDir   RdLnk   Statfs Mounted@\n",
  860. X            dwid, dwid, "What");
  861. X                        show_mt(mt, Stats, &mwid, &dwid, &twid);
  862. X                    } else {
  863. X                        fprintf(stderr, "%s: %s not automounted\n", progname, fs);
  864. X                    }
  865. X                    xdr_pri_free(xdr_amq_mount_tree_p, (caddr_t) mtp);
  866. X                } else {
  867. X                    fprintf(stderr, "%s: ", progname);
  868. X                    clnt_perror(clnt, server);
  869. X                    errs = 1;
  870. X                }
  871. X            }
  872. X        } while (optind < argc);
  873. X    } else if (unmount_flag) {
  874. X        goto show_usage;
  875. X    } else if (stats_flag) {
  876. X        amq_mount_stats *ms = amqproc_stats_1((voidp) 0, clnt);
  877. X        if (ms) {
  878. X            show_ms(ms);
  879. X        } else {
  880. X            fprintf(stderr, "%s: ", progname);
  881. X            clnt_perror(clnt, server);
  882. X            errs = 1;
  883. X        }
  884. X    } else if (!nodefault) {
  885. X        amq_mount_tree_list *mlp = amqproc_export_1((voidp) 0, clnt);
  886. X        if (mlp) {
  887. X            enum show_opt e = Calc;
  888. X            int mwid = 0, dwid = 0, pwid = 0;
  889. X            while (e != ShowDone) {
  890. X                int i;
  891. X                for (i = 0; i < mlp->amq_mount_tree_list_len; i++) {
  892. X                    show_mt(mlp->amq_mount_tree_list_val[i],
  893. X                         e, &mwid, &dwid, &pwid);
  894. X                }
  895. X                mwid++; dwid++, pwid++;
  896. X                if (e == Calc) e = Short;
  897. X                else if (e == Short) e = ShowDone;
  898. X            }
  899. X        } else {
  900. X            fprintf(stderr, "%s: ", progname);
  901. X            clnt_perror(clnt, server);
  902. X            errs = 1;
  903. X        }
  904. X    }
  905. X
  906. X    exit(errs);
  907. X}
  908. X
  909. X#ifdef DEBUG
  910. Xxfree(f, l, p)
  911. Xchar *f, *l;
  912. Xvoidp p;
  913. X{
  914. X    free(p);
  915. X}
  916. X#endif
  917. END_OF_FILE
  918. if test 11634 -ne `wc -c <'amq.c'`; then
  919.     echo shar: \"'amq.c'\" unpacked with wrong size!
  920. fi
  921. # end of 'amq.c'
  922. fi
  923. if test -f 'get_args.c' -a "${1}" != "-c" ; then 
  924.   echo shar: Will not clobber existing file \"'get_args.c'\"
  925. else
  926. echo shar: Extracting \"'get_args.c'\" \(10282 characters\)
  927. sed "s/^X//" >'get_args.c' <<'END_OF_FILE'
  928. X/*
  929. X * $Id: get_args.c,v 5.1.1.2 90/01/11 17:06:42 jsp Exp Locker: jsp $
  930. X *
  931. X * Copyright (c) 1990 Jan-Simon Pendry
  932. X * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
  933. X * Copyright (c) 1990 The Regents of the University of California.
  934. X * All rights reserved.
  935. X *
  936. X * This code is derived from software contributed to Berkeley by
  937. X * Jan-Simon Pendry at Imperial College, London.
  938. X *
  939. X * Redistribution and use in source and binary forms are permitted
  940. X * provided that the above copyright notice and this paragraph are
  941. X * duplicated in all such forms and that any documentation,
  942. X * advertising materials, and other materials related to such
  943. X * distribution and use acknowledge that the software was developed
  944. X * by Imperial College of Science, Technology and Medicine, London, UK.
  945. X * The names of the College and University may not be used to endorse
  946. X * or promote products derived from this software without specific
  947. X * prior written permission.
  948. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  949. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  950. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  951. X *
  952. X *    %W% (Berkeley) %G%
  953. X */
  954. X
  955. X/*
  956. X * Argument decode
  957. X */
  958. X
  959. X#include "am.h"
  960. X#ifdef HAS_SYSLOG
  961. X#include <syslog.h>
  962. X#endif
  963. X#include <sys/stat.h>
  964. X
  965. Xextern int optind;
  966. Xextern char *optarg;
  967. X
  968. X#if defined(DEBUG) && defined(PARANOID)
  969. Xchar **gargv;
  970. X#endif
  971. Xint restart_existing_mounts;
  972. Xint print_pid;
  973. Xint normalize_hosts;
  974. Xchar *karch;            /* Kernel architecture */
  975. Xchar *cluster;            /* Cluster name */
  976. X#ifdef HAS_YP_MAPS
  977. Xchar *domain;            /* YP domain */
  978. X#endif
  979. X#ifdef UPDATE_MTAB
  980. Xchar *mtab;
  981. X#endif
  982. XFILE *logfp = stderr;        /* Log errors to stderr initially */
  983. X#ifdef HAS_SYSLOG
  984. Xint syslogging;
  985. X#endif
  986. Xint afs_timeo = -1;
  987. Xint afs_retrans = -1;
  988. Xint am_timeo = AM_TTL;
  989. Xint am_timeo_w = AM_TTL_W;
  990. Xint xlog_level = 0;
  991. Xint xlog_level_init = ~0;
  992. X
  993. Xstruct opt_tab {
  994. X    char *opt;
  995. X    int flag;
  996. X};
  997. X
  998. X/*
  999. X * List of log options
  1000. X */
  1001. Xstatic struct opt_tab xlog_opt[] = {
  1002. X    { "all", XLOG_ALL },        /* All messages */
  1003. X#ifdef DEBUG
  1004. X    { "debug", XLOG_DEBUG },    /* Debug messages */
  1005. X#endif
  1006. X    { "error", XLOG_ERROR },    /* Non-fatal system errors */
  1007. X    { "fatal", XLOG_FATAL },    /* Fatal errors */
  1008. X    { "info", XLOG_INFO },        /* Information */
  1009. X    { "map", XLOG_MAP },        /* Map errors */
  1010. X    { "stats", XLOG_STATS },    /* Additional statistical information */
  1011. X    { "user", XLOG_USER },        /* Non-fatal user errors */
  1012. X    { "warn", XLOG_WARNING },    /* Warnings */
  1013. X    { "warning", XLOG_WARNING },    /* Warnings */
  1014. X    { 0, 0 }
  1015. X};
  1016. X
  1017. X#ifdef DEBUG
  1018. X/*
  1019. X * List of debug options.
  1020. X */
  1021. Xstatic struct opt_tab dbg_opt[] = {
  1022. X    { "all", D_ALL },        /* All */
  1023. X    { "amq", D_AMQ },        /* Register for AMQ program */
  1024. X    { "daemon", D_DAEMON },        /* Enter daemon mode */
  1025. X    { "full", D_FULL },        /* Program trace */
  1026. X    { "mem", D_MEM },        /* Trace memory allocations */
  1027. X    { "mtab", D_MTAB },        /* Use local mtab file */
  1028. X    { "str", D_STR },        /* Debug string munging */
  1029. X    { "test", D_TEST },        /* Full debug - but no daemon */
  1030. X    { "trace", D_TRACE },        /* Protocol trace */
  1031. X    { 0, 0 }
  1032. X};
  1033. X
  1034. Xint debug_flags = D_AMQ            /* Register AMQ */
  1035. X         |D_DAEMON        /* Enter daemon mode */
  1036. X         ;
  1037. X#endif
  1038. X
  1039. Xstatic void show_opts(ch, opts)
  1040. Xint ch;
  1041. Xstruct opt_tab *opts;
  1042. X{
  1043. X    /*
  1044. X     * Display current debug options
  1045. X     */
  1046. X    int i;
  1047. X    int s = '{';
  1048. X    fprintf(stderr, "\t[-%c {no}", ch);
  1049. X    for (i = 0; opts[i].opt; i++) {
  1050. X        fprintf(stderr, "%c%s", s, opts[i].opt);
  1051. X        s = ',';
  1052. X    }
  1053. X    fputs("}]\n", stderr);
  1054. X}
  1055. X
  1056. Xstatic int option(s, optb, flags)
  1057. Xchar *s;
  1058. Xstruct opt_tab *optb;
  1059. Xint *flags;
  1060. X{
  1061. X    char *p = s;
  1062. X    int errs = 0;
  1063. X
  1064. X    while (p && *p) {
  1065. X        int neg;
  1066. X        char *opt;
  1067. X        struct opt_tab *dp;
  1068. X
  1069. X        s = p;
  1070. X        p = strchr(p, ',');
  1071. X        if (p)
  1072. X            *p = '\0';
  1073. X
  1074. X        if (s[0] == 'n' && s[1] == 'o') {
  1075. X            opt = s + 2;
  1076. X            neg = 1;
  1077. X        } else {
  1078. X            opt = s;
  1079. X            neg = 0;
  1080. X        }
  1081. X
  1082. X        /*
  1083. X         * Scan the array of debug options to find the
  1084. X         * corresponding flag value.  If it is found
  1085. X         * then set (or clear) the flag (depending on
  1086. X         * whether the option was prefixed with "no").
  1087. X         */
  1088. X        for (dp = optb; dp->opt; dp++) {
  1089. X            if (strcmp(opt, dp->opt) == 0) {
  1090. X                if (neg)
  1091. X                    *flags &= ~dp->flag;
  1092. X                else
  1093. X                    *flags |= dp->flag;
  1094. X                break;
  1095. X            }
  1096. X        }
  1097. X
  1098. X        if (dp->opt == 0) {
  1099. X            /*
  1100. X             * This will log to stderr when parsing the command line
  1101. X             * since any -l option will not yet have taken effect.
  1102. X             */
  1103. X            plog(XLOG_USER, "option \"%s\" not recognised", s);
  1104. X            errs++;
  1105. X        }
  1106. X        /*
  1107. X         * Put the comma back
  1108. X         */
  1109. X        if (p)
  1110. X            *p++ = ',';
  1111. X    }
  1112. X
  1113. X    return errs;
  1114. X}
  1115. X
  1116. X/*
  1117. X * Switch on/off logging options
  1118. X */
  1119. Xint switch_option(opt)
  1120. Xchar *opt;
  1121. X{
  1122. X    int xl = xlog_level;
  1123. X    int rc = option(opt, xlog_opt, &xl);
  1124. X    if (rc) {
  1125. X        rc = EINVAL;
  1126. X    } else {
  1127. X        /*
  1128. X         * Keep track of initial log level, and
  1129. X         * don't allow options to be turned off.
  1130. X         */
  1131. X        if (xlog_level_init == ~0)
  1132. X            xlog_level_init = xl;
  1133. X        else
  1134. X            xl |= xlog_level_init;
  1135. X        xlog_level = xl;
  1136. X    }
  1137. X    return rc;
  1138. X}
  1139. X
  1140. X#ifdef DEBUG
  1141. X/*
  1142. X * Switch on/off debug options
  1143. X */
  1144. Xint debug_option(opt)
  1145. Xchar *opt;
  1146. X{
  1147. X    return option(opt, dbg_opt, &debug_flags);
  1148. X}
  1149. X#endif
  1150. X
  1151. X/*
  1152. X * Change current logfile
  1153. X */
  1154. Xint switch_to_logfile(logfile)
  1155. Xchar *logfile;
  1156. X{
  1157. X    FILE *new_logfp = stderr;
  1158. X
  1159. X    if (logfile) {
  1160. X#ifdef HAS_SYSLOG
  1161. X        syslogging = 0;
  1162. X#endif
  1163. X        if (strcmp(logfile, "/dev/stderr") == 0)
  1164. X            new_logfp = stderr;
  1165. X        else if (strcmp(logfile, "syslog") == 0) {
  1166. X#ifdef HAS_SYSLOG
  1167. X            syslogging = 1;
  1168. X            new_logfp = stderr;
  1169. X#ifdef LOG_CONS
  1170. X            openlog(progname, LOG_PID|LOG_CONS|LOG_NOWAIT,
  1171. X                LOG_DAEMON);
  1172. X#else
  1173. X            /* 4.2 compat mode - XXX */
  1174. X            openlog(progname, LOG_PID);
  1175. X#endif
  1176. X#else
  1177. X            plog(XLOG_WARNING, "syslog option not supported, logging unchanged");
  1178. X#endif
  1179. X        } else {
  1180. X            (void) umask(orig_umask);
  1181. X            new_logfp = fopen(logfile, "a");
  1182. X            umask(0);
  1183. X        }
  1184. X    }
  1185. X
  1186. X    /*
  1187. X     * If we couldn't open a new file, then continue using the old.
  1188. X     */
  1189. X    if (!new_logfp && logfile) {
  1190. X        plog(XLOG_USER, "%s: Can't open logfile: %m", logfile);
  1191. X        return 1;
  1192. X    }
  1193. X    /*
  1194. X     * Close the previous file
  1195. X     */
  1196. X    if (logfp && logfp != stderr)
  1197. X        (void) fclose(logfp);
  1198. X    logfp = new_logfp;
  1199. X    return 0;
  1200. X}
  1201. X
  1202. Xvoid get_args(c, v)
  1203. Xint c;
  1204. Xchar *v[];
  1205. X{
  1206. X    int opt_ch;
  1207. X    int usage = 0;
  1208. X    char *logfile = 0;
  1209. X    char *sub_domain = 0;
  1210. X
  1211. X#if defined(DEBUG) && defined(PARANOID)
  1212. X    gargv = v;
  1213. X    progname = v[0];        /* Use argv[0] to try to solve Piete's problem */
  1214. X#else
  1215. X    if (v[0]) {
  1216. X        progname = strrchr(v[0], '/');
  1217. X        if (progname && progname[1])
  1218. X            progname++;
  1219. X        else
  1220. X            progname = v[0];
  1221. X    }
  1222. X#endif
  1223. X    if (!progname)
  1224. X        progname = "amd";
  1225. X
  1226. X    while ((opt_ch = getopt(c, v, "mnprva:c:d:k:l:t:w:x:y:D:")) != EOF)
  1227. X    switch (opt_ch) {
  1228. X    case 'a':
  1229. X        if (*optarg != '/') {
  1230. X            fprintf(stderr, "%s: -a option must begin with a '/'\n",
  1231. X                    progname);
  1232. X            exit(1);
  1233. X        }
  1234. X        auto_dir = optarg;
  1235. X        break;
  1236. X
  1237. X    case 'c':
  1238. X        am_timeo = atoi(optarg);
  1239. X        if (am_timeo <= 0)
  1240. X            am_timeo = AM_TTL;
  1241. X        break;
  1242. X
  1243. X    case 'd':
  1244. X        sub_domain = optarg;
  1245. X        break;
  1246. X
  1247. X    case 'k':
  1248. X        karch = optarg;
  1249. X        break;
  1250. X
  1251. X    case 'l':
  1252. X        logfile = optarg;
  1253. X        break;
  1254. X
  1255. X    case 'm':
  1256. X        plog(XLOG_USER, "The -m option is no longer supported.");
  1257. X        plog(XLOG_USER, "... Use `ypcat -k am.master` on the command line instead");
  1258. X        break;
  1259. X
  1260. X    case 'n':
  1261. X        normalize_hosts = 1;
  1262. X        break;
  1263. X
  1264. X    case 'p':
  1265. X        print_pid = 1;
  1266. X        break;
  1267. X
  1268. X    case 'r':
  1269. X        restart_existing_mounts = 1;
  1270. X        break;
  1271. X
  1272. X    case 't':
  1273. X        /* timeo.retrans */
  1274. X        { char *dot = strchr(optarg, '.');
  1275. X          if (dot) *dot = '\0';
  1276. X          if (*optarg) {
  1277. X            afs_timeo = atoi(optarg);
  1278. X          }
  1279. X          if (dot) {
  1280. X              afs_retrans = atoi(dot+1);
  1281. X            *dot = '.';
  1282. X          }
  1283. X        }
  1284. X        break;
  1285. X
  1286. X    case 'v':
  1287. X        { char buf[256];
  1288. X          show_rcs_info(version, buf);
  1289. X          fputs(buf, stderr);
  1290. X        }
  1291. X        fprintf(stderr,
  1292. X            " for a%s %s running %s (%s-endian)\n",
  1293. X                    strchr("aeiou", arch[0]) ? "n" : "",
  1294. X                    arch, op_sys, endian);
  1295. X        fputs("Map support for: ", stderr);
  1296. X        mapc_showtypes(stderr);
  1297. X        fputs(".\n", stderr);
  1298. X        exit(0);
  1299. X        break;
  1300. X
  1301. X    case 'w':
  1302. X        am_timeo_w = atoi(optarg);
  1303. X        if (am_timeo_w <= 0)
  1304. X            am_timeo_w = AM_TTL_W;
  1305. X        break;
  1306. X
  1307. X    case 'x':
  1308. X        usage += switch_option(optarg);
  1309. X        break;
  1310. X
  1311. X    case 'y':
  1312. X#ifdef HAS_YP_MAPS
  1313. X        domain = optarg;
  1314. X#else
  1315. X        plog(XLOG_USER, "-y: option ignored.  No YP support available.");
  1316. X#endif
  1317. X        break;
  1318. X
  1319. X    case 'C':
  1320. X        cluster = optarg;
  1321. X        break;
  1322. X
  1323. X    case 'D':
  1324. X#ifdef DEBUG
  1325. X        usage += debug_option(optarg);
  1326. X#else
  1327. X        fprintf(stderr, "%s: not compiled with DEBUG option -- sorry.\n", progname);
  1328. X#endif
  1329. X        break;
  1330. X
  1331. X    default:
  1332. X        usage = 1;
  1333. X        break;
  1334. X    }
  1335. X
  1336. X    if (xlog_level == 0) {
  1337. X        /* Take copy to avoid writable-strings problem */
  1338. X        char *dfstr = strdup(XLOG_DEFSTR);
  1339. X        usage += switch_option(dfstr);
  1340. X        free((voidp) dfstr);
  1341. X#ifdef DEBUG
  1342. X        usage += switch_option("debug");
  1343. X#endif
  1344. X    } else {
  1345. X#ifdef DEBUG
  1346. X        usage += switch_option("debug");
  1347. X#endif
  1348. X    }
  1349. X
  1350. X    if (usage)
  1351. X        goto show_usage;
  1352. X
  1353. X    while (optind <= c-2) {
  1354. X        char *dir = v[optind++];
  1355. X        char *map = v[optind++];
  1356. X        char *opts = "";
  1357. X        if (v[optind] && *v[optind] == '-')
  1358. X            opts = &v[optind++][1];
  1359. X
  1360. X        root_newmap(dir, opts, map);
  1361. X    }
  1362. X
  1363. X    if (optind == c) {
  1364. X#ifdef hpux
  1365. X        /*
  1366. X         * HP-UX can't handle ./mtab
  1367. X         * That system is sick - really.
  1368. X         */
  1369. X#ifdef    DEBUG
  1370. X        debug_option("nomtab");
  1371. X#endif    /* DEBUG */
  1372. X#endif    /* hpux */
  1373. X
  1374. X        /*
  1375. X         * Append domain name to hostname.
  1376. X         * sub_domain overrides hostdomain
  1377. X         * if given.
  1378. X         */
  1379. X        if (sub_domain)
  1380. X            hostdomain = sub_domain;
  1381. X        if (*hostdomain == '.')
  1382. X            hostdomain++;
  1383. X        strcat(hostd,  ".");
  1384. X        strcat(hostd, hostdomain);
  1385. X
  1386. X#ifdef UPDATE_MTAB
  1387. X#ifdef DEBUG
  1388. X        if (debug_flags & D_MTAB)
  1389. X            mtab = DEBUG_MTAB;
  1390. X        else
  1391. X#endif /* DEBUG */
  1392. X        mtab = MOUNTED;
  1393. X#else
  1394. X#ifdef DEBUG
  1395. X        { if (debug_flags & D_MTAB) {
  1396. X            dlog("-D mtab option ignored");
  1397. X        } }
  1398. X#endif /* DEBUG */
  1399. X#endif /* UPDATE_MTAB */
  1400. X
  1401. X        if (switch_to_logfile(logfile) != 0)
  1402. X            plog(XLOG_USER, "Cannot switch logfile");
  1403. X
  1404. X        /*
  1405. X         * If the kernel architecture was not specified
  1406. X         * then use the machine architecture.
  1407. X         */
  1408. X        if (karch == 0)
  1409. X            karch = arch;
  1410. X
  1411. X        if (cluster == 0)
  1412. X            cluster = hostdomain;
  1413. X
  1414. X        if (afs_timeo <= 0)
  1415. X            afs_timeo = AFS_TIMEO;
  1416. X        if (afs_retrans <= 0)
  1417. X            afs_retrans = AFS_RETRANS;
  1418. X        if (afs_retrans <= 0)
  1419. X            afs_retrans = 3;    /* XXX */
  1420. X        return;
  1421. X    }
  1422. X
  1423. Xshow_usage:
  1424. X    fprintf(stderr,
  1425. X"Usage: %s [-mnprv] [-a mnt_point] [-c cache_time] [-d domain]\n\
  1426. X\t[-k kernel_arch] [-l logfile|\"syslog\"] [-t afs_timeout]\n\
  1427. X\t[-w wait_timeout] [-C cluster_name]", progname);
  1428. X
  1429. X#ifdef HAS_YP_MAPS
  1430. X    fputs(" [-y yp-domain]\n", stderr);
  1431. X#else
  1432. X    fputc('\n', stderr);
  1433. X#endif
  1434. X
  1435. X    show_opts('x', xlog_opt);
  1436. X#ifdef DEBUG
  1437. X    show_opts('D', dbg_opt);
  1438. X#endif
  1439. X    fprintf(stderr, "\t{directory mapname [-map_options]} ...\n");
  1440. X    exit(1);
  1441. X}
  1442. END_OF_FILE
  1443. if test 10282 -ne `wc -c <'get_args.c'`; then
  1444.     echo shar: \"'get_args.c'\" unpacked with wrong size!
  1445. fi
  1446. # end of 'get_args.c'
  1447. fi
  1448. if test -f 'mapc.c' -a "${1}" != "-c" ; then 
  1449.   echo shar: Will not clobber existing file \"'mapc.c'\"
  1450. else
  1451. echo shar: Extracting \"'mapc.c'\" \(11592 characters\)
  1452. sed "s/^X//" >'mapc.c' <<'END_OF_FILE'
  1453. X/*
  1454. X * $Id: mapc.c,v 5.1.1.1 89/11/28 17:52:47 jsp Exp Locker: jsp $
  1455. X *
  1456. X * Copyright (c) 1989 Jan-Simon Pendry
  1457. X * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
  1458. X * Copyright (c) 1989 The Regents of the University of California.
  1459. X * All rights reserved.
  1460. X *
  1461. X * This code is derived from software contributed to Berkeley by
  1462. X * Jan-Simon Pendry at Imperial College, London.
  1463. X *
  1464. X * Redistribution and use in source and binary forms are permitted
  1465. X * provided that the above copyright notice and this paragraph are
  1466. X * duplicated in all such forms and that any documentation,
  1467. X * advertising materials, and other materials related to such
  1468. X * distribution and use acknowledge that the software was developed
  1469. X * by Imperial College of Science, Technology and Medicine, London, UK.
  1470. X * The names of the College and University may not be used to endorse
  1471. X * or promote products derived from this software without specific
  1472. X * prior written permission.
  1473. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1474. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1475. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1476. X *
  1477. X *    %W% (Berkeley) %G%
  1478. X */
  1479. X
  1480. X/*
  1481. X * Mount map cache
  1482. X */
  1483. X
  1484. X#include "am.h"
  1485. X
  1486. X/*
  1487. X * Hash table size
  1488. X */
  1489. X#define    NKVHASH    (1 << 2)        /* Power of two */
  1490. X
  1491. X/*
  1492. X * Wildcard key
  1493. X */
  1494. Xstatic char wildcard[] = "*";
  1495. X
  1496. X/*
  1497. X * Map cache types
  1498. X * default, none, incremental, all
  1499. X */
  1500. X#define    MAPC_DFLT    -1
  1501. X#define    MAPC_NONE    0
  1502. X#define    MAPC_INC    1
  1503. X#define    MAPC_ALL    2
  1504. X
  1505. X/*
  1506. X * Do a map reload
  1507. X */
  1508. X#define mapc_reload_map(m) \
  1509. X    ((*(m)->reload)(m, m->map_name, mapc_add_kv))
  1510. X
  1511. X/*
  1512. X * Cache map operations
  1513. X */
  1514. Xtypedef void add_fn P((mnt_map*, char*, char*));
  1515. Xtypedef int init_fn P((char*));
  1516. Xtypedef int search_fn P((mnt_map*, char*, char*, char**, time_t*));
  1517. Xtypedef int reload_fn P((mnt_map*, char*, add_fn*));
  1518. X
  1519. Xstatic void mapc_sync P((mnt_map*));
  1520. X
  1521. X/*
  1522. X * Map type
  1523. X */
  1524. Xtypedef struct map_type map_type;
  1525. Xstruct map_type {
  1526. X    char *name;            /* Name of this map type */
  1527. X    init_fn *init;            /* Initialisation */
  1528. X    reload_fn *reload;        /* Reload or fill */
  1529. X    search_fn *search;        /* Search for new entry */
  1530. X    int def_alloc;            /* Default allocation mode */
  1531. X};
  1532. X
  1533. X/*
  1534. X * Key-value pair
  1535. X */
  1536. Xtypedef struct kv kv;
  1537. Xstruct kv {
  1538. X    kv *next;
  1539. X    char *key;
  1540. X    char *val;
  1541. X};
  1542. X
  1543. Xstruct mnt_map {
  1544. X    qelem hdr;
  1545. X    int refc;            /* Reference count */
  1546. X    int alloc;            /* Allocation mode */
  1547. X    time_t modify;            /* Modify time of map */
  1548. X    char *map_name;            /* Name of this map */
  1549. X    char *wildcard;            /* Wildcard value */
  1550. X    reload_fn *reload;        /* Function to be used for reloads */
  1551. X    search_fn *search;        /* Function to be used for searching */
  1552. X    kv *kvhash[NKVHASH];        /* Cached data */
  1553. X};
  1554. X
  1555. X/*
  1556. X * Map for root node
  1557. X */
  1558. Xstatic mnt_map *root_map;
  1559. X
  1560. X/*
  1561. X * List of known maps
  1562. X */
  1563. Xextern qelem map_list_head;
  1564. Xqelem map_list_head = { &map_list_head, &map_list_head };
  1565. X
  1566. X/*
  1567. X * Configuration
  1568. X */
  1569. X/* ROOT MAP */
  1570. Xstatic int root_init P((char*));
  1571. X
  1572. X/* FILE MAPS */
  1573. X#ifdef HAS_FILE_MAPS
  1574. Xextern int file_init P((char*));
  1575. Xextern int file_reload P((mnt_map*, char*, add_fn*));
  1576. Xextern int file_search P((mnt_map*, char*, char*, char**, time_t*));
  1577. X#endif
  1578. X
  1579. X/* YELLOW PAGES MAPS */
  1580. X#ifdef HAS_YP_MAPS
  1581. Xextern int yp_init P((char*));
  1582. Xextern int yp_search P((mnt_map*, char*, char*, char**, time_t*));
  1583. X#endif
  1584. X
  1585. X/* GDBM MAPS */
  1586. X#ifdef HAS_GDBM_MAPS
  1587. X#define HAS_DATABASE
  1588. X#undef HAS_NDBM_MAPS
  1589. Xextern int gdbm_init P((char*));
  1590. Xextern int gdbm_search P((mnt_map*, char*, char*, char**, time_t*));
  1591. X#endif
  1592. X
  1593. X/* NDBM MAPS */
  1594. X#ifndef HAS_DATABASE
  1595. X#ifdef HAS_NDBM_MAPS
  1596. X#ifdef OS_HAS_NDBM
  1597. X#define    HAS_DATABASE
  1598. X#undef HAS_GDBM_MAPS
  1599. Xextern int ndbm_init P((char*));
  1600. Xextern int ndbm_search P((mnt_map*, char*, char*, char**, time_t*));
  1601. X#endif
  1602. X#endif
  1603. X#endif
  1604. X
  1605. X/* HESIOD MAPS */
  1606. X#ifdef HAS_HESIOD_MAPS
  1607. Xextern int hesiod_init P((char*));
  1608. Xextern int hesiod_search P((mnt_map*, char*, char*, char**, time_t*));
  1609. X#endif
  1610. X
  1611. X/* ERROR MAP */
  1612. Xstatic int error_init P((char*));
  1613. Xstatic int error_reload P((mnt_map*, char*, add_fn*));
  1614. Xstatic int error_search P((mnt_map*, char*, char*, char**, time_t*));
  1615. X
  1616. Xstatic map_type maptypes[] = {
  1617. X    { "root", root_init, error_reload, error_search, MAPC_ALL },
  1618. X
  1619. X#ifdef HAS_HESIOD_MAPS
  1620. X    { "hesiod", hesiod_init, error_reload, hesiod_search, MAPC_INC },
  1621. X#endif
  1622. X
  1623. X#ifdef HAS_YP_MAPS
  1624. X    { "yp", yp_init, error_reload, yp_search, MAPC_INC },
  1625. X#endif
  1626. X
  1627. X#ifdef HAS_NDBM_MAPS
  1628. X    { "ndbm", ndbm_init, error_reload, ndbm_search, MAPC_INC },
  1629. X#endif
  1630. X
  1631. X#ifdef HAS_GDBM_MAPS
  1632. X    { "gdbm", gdbm_init, error_reload, gdbm_search, MAPC_INC },
  1633. X#endif
  1634. X
  1635. X#ifdef HAS_FILE_MAPS
  1636. X    { "file", file_init, file_reload, file_search, MAPC_ALL },
  1637. X#endif
  1638. X
  1639. X    { "error", error_init, error_reload, error_search, MAPC_NONE },
  1640. X};
  1641. X
  1642. X/*
  1643. X * Hash function
  1644. X */
  1645. Xstatic unsigned int kvhash_of(key)
  1646. Xchar *key;
  1647. X{
  1648. X    unsigned int i, j;
  1649. X
  1650. X    for (i = 0; j = *key++; i += j)
  1651. X        ;
  1652. X
  1653. X    return i % NKVHASH;
  1654. X}
  1655. X
  1656. Xvoid mapc_showtypes(fp)
  1657. XFILE *fp;
  1658. X{
  1659. X    map_type *mt;
  1660. X    char *sep = "";
  1661. X    for (mt = maptypes; mt < maptypes+sizeof(maptypes)/sizeof(maptypes[0]); mt++) {
  1662. X        fprintf(fp, "%s%s", sep, mt->name);
  1663. X        sep = ", ";
  1664. X    }
  1665. X}
  1666. X
  1667. X/*
  1668. X * Add key and val to the map m.
  1669. X * key and val are assumed to be safe copies
  1670. X */
  1671. Xvoid mapc_add_kv(m, key, val)
  1672. Xmnt_map *m;
  1673. Xchar *key;
  1674. Xchar *val;
  1675. X{
  1676. X    kv **h = &m->kvhash[kvhash_of(key)];
  1677. X    kv *n = ALLOC(kv);
  1678. X    n->key = key;
  1679. X    n->val = val;
  1680. X    n->next = *h;
  1681. X    *h = n;
  1682. X}
  1683. X
  1684. Xstatic int search_map(m, key, valp)
  1685. Xmnt_map *m;
  1686. Xchar *key;
  1687. Xchar **valp;
  1688. X{
  1689. X    int rc;
  1690. X    do {
  1691. X        rc = (*m->search)(m, m->map_name, key, valp, &m->modify);
  1692. X        if (rc < 0) {
  1693. X            plog(XLOG_MAP, "Re-synchronizing cache for map %s", m->map_name);
  1694. X            mapc_sync(m);
  1695. X        }
  1696. X    } while (rc < 0);
  1697. X
  1698. X    return rc;
  1699. X}
  1700. X
  1701. X/*
  1702. X * Do a wildcard lookup in the map and
  1703. X * save the result.
  1704. X */
  1705. Xstatic void mapc_find_wildcard(m)
  1706. Xmnt_map *m;
  1707. X{
  1708. X    /*
  1709. X     * Attempt to find the wildcard entry
  1710. X     */
  1711. X    int rc = search_map(m, wildcard, &m->wildcard);
  1712. X
  1713. X    if (rc != 0)
  1714. X        m->wildcard = 0;
  1715. X}
  1716. X
  1717. X/*
  1718. X * Make a duplicate reference to an existing map
  1719. X */
  1720. X#define mapc_dup(m) ((m)->refc++, (m))
  1721. X
  1722. X/*
  1723. X * Create a new map
  1724. X */
  1725. Xstatic mnt_map *mapc_create(map, opt)
  1726. Xchar *map;
  1727. Xchar *opt;
  1728. X{
  1729. X    mnt_map *m = ALLOC(mnt_map);
  1730. X    map_type *mt;
  1731. X    int alloc = STREQ(opt, "all") ? MAPC_ALL :
  1732. X            (STREQ(opt, "inc") ? MAPC_INC :
  1733. X            ((STREQ(opt, "default") || STREQ(opt, "mapdefault")) ? MAPC_DFLT :
  1734. X            MAPC_NONE));
  1735. X
  1736. X    for (mt = maptypes; mt < maptypes+sizeof(maptypes)/sizeof(maptypes[0]); mt++)
  1737. X        if ((*mt->init)(map) == 0)
  1738. X            break;
  1739. X
  1740. X#ifdef DEBUG
  1741. X    dlog("Map for %s coming from maptype %s", map, mt->name);
  1742. X#endif
  1743. X    /*
  1744. X     * If there is no support for reload and it was requested
  1745. X     * then back off to incremental instead.
  1746. X     */
  1747. X    if (mt->reload == error_reload && alloc == MAPC_ALL && mt->def_alloc != MAPC_ALL) {
  1748. X        plog(XLOG_WARNING, "Map type \"%s\" does not support cache type \"all\"",
  1749. X                    mt->name);
  1750. X        alloc = MAPC_INC;
  1751. X    } else if (alloc == MAPC_DFLT)
  1752. X        alloc = mt->def_alloc;
  1753. X    m->alloc = alloc;
  1754. X    m->reload = mt->reload;
  1755. X    m->modify = clocktime();
  1756. X    m->search = alloc == MAPC_ALL ? error_search : mt->search;
  1757. X    bzero((voidp) m->kvhash, sizeof(m->kvhash));
  1758. X    m->map_name = strdup(map);
  1759. X    m->refc = 1;
  1760. X    /*
  1761. X     * Attempt to find the wildcard entry
  1762. X     */
  1763. X    mapc_find_wildcard(m);
  1764. X
  1765. X    if (alloc == MAPC_ALL) {
  1766. X        /*
  1767. X         * If cache all is specified then load the cache
  1768. X         */
  1769. X        if (mapc_reload_map(m)) {
  1770. X            /*
  1771. X             * If that doesn't work then fallback to
  1772. X             * incremental cache mode
  1773. X             */
  1774. X            m->alloc = MAPC_INC;
  1775. X        }
  1776. X    }
  1777. X    return m;
  1778. X}
  1779. X
  1780. X/*
  1781. X * Free the cached data in a map
  1782. X */
  1783. Xstatic void mapc_clear(m)
  1784. Xmnt_map *m;
  1785. X{
  1786. X    int i;
  1787. X
  1788. X    /*
  1789. X     * For each of the hash slots, chain
  1790. X     * along free'ing the data.
  1791. X     */
  1792. X    for (i = 0; i < NKVHASH; i++) {
  1793. X        kv *k = m->kvhash[i];
  1794. X        while (k) {
  1795. X            kv *n = k->next;
  1796. X            free(k->key);
  1797. X            if (k->val)
  1798. X                free(k->val);
  1799. X            free(k);
  1800. X            k = n;
  1801. X        }
  1802. X    }
  1803. X    /*
  1804. X     * Zero the hash slots
  1805. X     */
  1806. X    bzero((voidp) m->kvhash, sizeof(m->kvhash));
  1807. X    /*
  1808. X     * Free the wildcard if it exists
  1809. X     */
  1810. X    if (m->wildcard) {
  1811. X        free(m->wildcard);
  1812. X        m->wildcard = 0;
  1813. X    }
  1814. X}
  1815. X
  1816. X/*
  1817. X * Find a map, or create one if it does not exist
  1818. X */
  1819. Xmnt_map *mapc_find(map, opt)
  1820. Xchar *map;
  1821. Xchar *opt;
  1822. X{
  1823. X    mnt_map *m;
  1824. X
  1825. X    /*
  1826. X     * Search the list of known maps to see if
  1827. X     * it has already been loaded.  If it is found
  1828. X     * then return a duplicate reference to it.
  1829. X     * Otherwise make a new map as required and
  1830. X     * add it to the list of maps
  1831. X     */
  1832. X    ITER(m, mnt_map, &map_list_head)
  1833. X        if (STREQ(m->map_name, map))
  1834. X            return mapc_dup(m);
  1835. X
  1836. X    m = mapc_create(map, opt);
  1837. X    ins_que(&m->hdr, &map_list_head);
  1838. X    return m;
  1839. X}
  1840. X
  1841. X/*
  1842. X * Free a map.
  1843. X */
  1844. Xvoid mapc_free(m)
  1845. Xmnt_map *m;
  1846. X{
  1847. X    /*
  1848. X     * Decrement the reference count.
  1849. X     * If the reference count hits zero
  1850. X     * then throw the map away.
  1851. X     */
  1852. X    if (--m->refc == 0) {
  1853. X        mapc_clear(m);
  1854. X        free(m->map_name);
  1855. X        rem_que(&m->hdr);
  1856. X        free(m);
  1857. X    }
  1858. X}
  1859. X
  1860. X/*
  1861. X * Search the map for the key.
  1862. X * Put a safe copy in *pval or return
  1863. X * an error code
  1864. X */
  1865. Xint mapc_search(m, key, pval)
  1866. Xmnt_map *m;
  1867. Xchar *key;
  1868. Xchar **pval;
  1869. X{
  1870. X    int error = 0;
  1871. X    kv *k;
  1872. X
  1873. X    /*
  1874. X     * Compute the hash table offset
  1875. X     */
  1876. X    k = m->kvhash[kvhash_of(key)];
  1877. X
  1878. X    /*
  1879. X     * Scan the linked list for the key
  1880. X     */
  1881. X    while (k && !FSTREQ(k->key, key))
  1882. X        k = k->next;
  1883. X
  1884. X    /*
  1885. X     * If found then take a copy
  1886. X     */
  1887. X    if (k) {
  1888. X        if (k->val)
  1889. X            *pval = strdup(k->val);
  1890. X        else
  1891. X            error = ENOENT;
  1892. X    } else if (m->alloc == MAPC_ALL) {
  1893. X        /*
  1894. X         * If the entire map is cached then this
  1895. X         * key does not exist.
  1896. X         */
  1897. X        error = ENOENT;
  1898. X    } else {
  1899. X        /*
  1900. X         * Otherwise search the map.  If we are
  1901. X         * in incremental mode then add the key
  1902. X         * to the cache.
  1903. X         */
  1904. X        error = search_map(m, key, pval);
  1905. X        if (!error && m->alloc == MAPC_INC)
  1906. X            mapc_add_kv(m, strdup(key), strdup(*pval));
  1907. X    }
  1908. X
  1909. X    /*
  1910. X     * If an error, and a wildcard exists,
  1911. X     * and the key is not internal then
  1912. X     * return a copy of the wildcard.
  1913. X     */
  1914. X    if (error && m->wildcard && *key != '/') {
  1915. X        *pval = strdup(m->wildcard);
  1916. X        return 0;
  1917. X    }
  1918. X
  1919. X    return error;
  1920. X}
  1921. X
  1922. Xstatic void mapc_sync(m)
  1923. Xmnt_map *m;
  1924. X{
  1925. X    mapc_clear(m);
  1926. X
  1927. X    if (m->alloc == MAPC_ALL)
  1928. X        if (mapc_reload_map(m))
  1929. X            m->alloc = MAPC_INC;
  1930. X    mapc_find_wildcard(m);
  1931. X}
  1932. X
  1933. X/*
  1934. X * Reload all the maps
  1935. X * Called when amd gets hit by a SIGHUP.
  1936. X */
  1937. Xvoid mapc_reload()
  1938. X{
  1939. X    mnt_map *m;
  1940. X
  1941. X    /*
  1942. X     * For all the maps,
  1943. X     * Throw away the existing information.
  1944. X     * Do a reload
  1945. X     * Find the wildcard
  1946. X     */
  1947. X    ITER(m, mnt_map, &map_list_head)
  1948. X        mapc_sync(m);
  1949. X}
  1950. X
  1951. X/*
  1952. X * Root map.
  1953. X * The root map is used to bootstrap amd.
  1954. X * All the require top-level mounts are added
  1955. X * into the root map and then the map is iterated
  1956. X * and a lookup is done on all the mount points.
  1957. X * This causes the top level mounts to be automounted.
  1958. X */
  1959. X
  1960. Xstatic int root_init(map)
  1961. Xchar *map;
  1962. X{
  1963. X    return strcmp(map, ROOT_MAP) == 0 ? 0 : ENOENT;
  1964. X}
  1965. X
  1966. X/*
  1967. X * Add a new entry to the root map
  1968. X *
  1969. X * dir - directory (key)
  1970. X * opts - mount options
  1971. X * map - map name
  1972. X */
  1973. Xvoid root_newmap(dir, opts, map)
  1974. Xchar *dir;
  1975. Xchar *opts;
  1976. Xchar *map;
  1977. X{
  1978. X    char str[MAXPATHLEN];
  1979. X
  1980. X    if (!root_map)
  1981. X        root_map = mapc_find(ROOT_MAP, "all");
  1982. X
  1983. X    dir = strdup(dir);
  1984. X    sprintf(str, "cache:=none;type:=auto;fs:=\"%s\";%s", map, opts ? opts : "");
  1985. X    mapc_add_kv(root_map, dir, strdup(str));
  1986. X}
  1987. X
  1988. X/*
  1989. X * Iterate of the the root map
  1990. X * and call (*fn)() on the key
  1991. X * of all the nodes.
  1992. X * Finally throw away the root map.
  1993. X */
  1994. Xint root_keyiter(fn)
  1995. Xvoid (*fn)P((char*));
  1996. X{
  1997. X    int i;
  1998. X    int c = 0;
  1999. X
  2000. X    if (root_map) {
  2001. X        for (i = 0; i < NKVHASH; i++) {
  2002. X            kv *k = root_map->kvhash[i];
  2003. X            while (k) {
  2004. X                (*fn)(k->key);
  2005. X                k = k->next;
  2006. X                c++;
  2007. X            }
  2008. X        }
  2009. X        mapc_free(root_map);
  2010. X        root_map = 0;
  2011. X    }
  2012. X    return c;
  2013. X}
  2014. X
  2015. X/*
  2016. X * Error map
  2017. X */
  2018. Xstatic int error_init(map)
  2019. Xchar *map;
  2020. X{
  2021. X    return 0;
  2022. X}
  2023. X
  2024. X/*ARGSUSED*/
  2025. Xstatic int error_search(m, map, key, pval, tp)
  2026. Xmnt_map *m;
  2027. Xchar *map;
  2028. Xchar *key;
  2029. Xchar **pval;
  2030. Xtime_t *tp;
  2031. X{
  2032. X    return ENOENT;
  2033. X}
  2034. X
  2035. X/*ARGSUSED*/
  2036. Xstatic int error_reload(m, map, fn)
  2037. Xmnt_map *m;
  2038. Xchar *map;
  2039. Xadd_fn *fn;
  2040. X{
  2041. X    return ENOENT;
  2042. X}
  2043. END_OF_FILE
  2044. if test 11592 -ne `wc -c <'mapc.c'`; then
  2045.     echo shar: \"'mapc.c'\" unpacked with wrong size!
  2046. fi
  2047. # end of 'mapc.c'
  2048. fi
  2049. echo shar: End of archive 7 \(of 13\).
  2050. cp /dev/null ark7isdone
  2051. MISSING=""
  2052. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  2053.     if test ! -f ark${I}isdone ; then
  2054.     MISSING="${MISSING} ${I}"
  2055.     fi
  2056. done
  2057. if test "${MISSING}" = "" ; then
  2058.     echo You have unpacked all 13 archives.
  2059.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2060. else
  2061.     echo You still need to unpack the following archives:
  2062.     echo "        " ${MISSING}
  2063. fi
  2064. ##  End of shell archive.
  2065. exit 0
  2066. exit 0 # Just in case...
  2067.